﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using LibSpeedShot;
using System.IO;
using Win32;

namespace SpeedShot
{
	public partial class SettingsForm : Form
	{
		private KeyboardHook hook = new KeyboardHook();
		private Capture cap = new Capture();
		private ListItem[] modKeys = new ListItem[5];
		private List<ListItem> screenKeys = new List<ListItem>();
		private List<ListItem> windowKeys = new List<ListItem>();
		private List<ListItem> regionKeys = new List<ListItem>();
		private int ShotNumber;
		private string mostRecentCapture = String.Empty;

		public SettingsForm()
		{
			InitializeComponent();
		}

		private void SettingsForm_Load(object sender, EventArgs e)
		{
			LoadModifiers();
			LoadSettings();

			hook.KeyPressed += new EventHandler<KeyPressedEventArgs>(hook_KeyPressed);
			RegisterHotKeys();
		}

		private void LoadModifiers()
		{
			modKeys[0] = new ListItem("None", 0);
			modKeys[1] = new ListItem("Alt", 1);
			modKeys[2] = new ListItem("Ctrl", 2);
			modKeys[3] = new ListItem("Shift", 4);
			modKeys[4] = new ListItem("Win", 8);

			windowKeys.AddRange(modKeys);
			screenKeys.AddRange(modKeys);
			regionKeys.AddRange(modKeys);

			cmboRegionModifier.DataSource = regionKeys;
			cmboRegionModifier.DisplayMember = "Key";
			cmboRegionModifier.ValueMember = "Value";

			cmboWindowModifier.DataSource = windowKeys;
			cmboWindowModifier.DisplayMember = "Key";
			cmboWindowModifier.ValueMember = "Value";

			cmboScreenModifier.DataSource = screenKeys;
			cmboScreenModifier.DisplayMember = "Key";
			cmboScreenModifier.ValueMember = "Value";
		}

		private void LoadSettings()
		{
			txtSaveDir.Text = Properties.Settings.Default.SaveDirectory;
			cmboSaveFile.Text = Properties.Settings.Default.SaveFileName;
			cmboSaveSuffix.Text = Properties.Settings.Default.SaveSuffix;
			cap.CopyToClipboard = chkCopyClipboard.Checked = Properties.Settings.Default.CopyToClipboard;
			chkUseTitle.Checked = Properties.Settings.Default.UseWindowTitles;
			chkPromptSave.Checked = Properties.Settings.Default.PromptSave;
			chkShowTips.Checked = Properties.Settings.Default.ShowTips;

			cmboScreenModifier.SelectedIndex = Properties.Settings.Default.CaptureScreenModifier;
			cmboWindowModifier.SelectedIndex = Properties.Settings.Default.CaptureWindowModifier;
			cmboRegionModifier.SelectedIndex = Properties.Settings.Default.CaptureRegionModifier;

			btnColor.BackColor = Properties.Settings.Default.RegionWindowColor;
			trackOpacity.Value = Properties.Settings.Default.RegonWindowOpacity;
			chkCaptureTaskbar.Checked = Properties.Settings.Default.CaptureTaskbar;

			ShotNumber = Properties.Settings.Default.ShotNumber;
		}

		private void RegisterHotKeys()
		{
			try
			{
				hook.RegisterHotKey((ControlKeys)Properties.Settings.Default.CaptureScreenModifier, Keys.PrintScreen);
				hook.RegisterHotKey((ControlKeys)Properties.Settings.Default.CaptureWindowModifier, Keys.PrintScreen);
				hook.RegisterHotKey((ControlKeys)Properties.Settings.Default.CaptureRegionModifier, Keys.PrintScreen);
			}
			catch { }
		}

		void hook_KeyPressed(object sender, KeyPressedEventArgs e)
		{
			bool result = false;
			string filePath = String.Empty;

			if (e.Modifier == (ControlKeys)Properties.Settings.Default.CaptureRegionModifier)
			{
				filePath = GetFilePath(false);
				result = cap.CaptureRegion(filePath, Properties.Settings.Default.RegionWindowColor,
					Properties.Settings.Default.RegonWindowOpacity);
			}

			if (e.Modifier == (ControlKeys)Properties.Settings.Default.CaptureScreenModifier)
			{
				filePath = GetFilePath(false);
				result = cap.CaptureScreen(filePath, Properties.Settings.Default.CaptureTaskbar);
			}

			if (e.Modifier == (ControlKeys)Properties.Settings.Default.CaptureWindowModifier)
			{
				if (Properties.Settings.Default.UseWindowTitles)
				{
					filePath = GetFilePath(true);
					result = cap.CaptureWindow(filePath);
				}
				else
				{
					filePath =  GetFilePath(false);
					result = cap.CaptureWindow(filePath);
				}
			}

			if (Properties.Settings.Default.ShowTips && result)
			{
				mostRecentCapture = filePath;
				notifyIconMain.ShowBalloonTip(1000, "Speed Shot", "Shot saved to...\n" + filePath, ToolTipIcon.Info);
			}

		}

		private string GetFilePath(bool useTitle)
		{
			//if CURRENTDATE, append date to directory\filename
			//if usetitle - append title to directory\filename, then append suffix

			string directory = String.Empty;
			string fileName = String.Empty;
			string fileSuffix = String.Empty;
			string title = String.Empty;
			string fullPath = String.Empty;

			if (Directory.Exists(Properties.Settings.Default.SaveDirectory)) { directory = Properties.Settings.Default.SaveDirectory; }
			else { directory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); }

			fileName = GetFileName(useTitle);

			if (!String.IsNullOrEmpty(Properties.Settings.Default.SaveSuffix)) { fileSuffix = GetFileSuffix(Path.Combine(directory, fileName)); }

			fileName = fileName + fileSuffix + title + ".png";

			if (Properties.Settings.Default.PromptSave)
			{
				SaveFileDialog sfd = new SaveFileDialog();
				sfd.Filter = "PNG Files|*.png";
				sfd.DefaultExt = ".png";
				sfd.AddExtension = true;
				sfd.InitialDirectory = directory;
				sfd.FileName = fileName;

				DialogResult res = sfd.ShowDialog();
				if (res != DialogResult.Cancel) { fullPath = sfd.FileName; }
				else { fullPath = Path.Combine(directory, fileName); }
			}
			else
			{
				
				fullPath = Path.Combine(directory, fileName);
			}

			return fullPath;
		}

		private string GetFileSuffix(string fileName)
		{
			switch (Properties.Settings.Default.SaveSuffix)
			{
				case "CURRENTDATE":
					return DateTime.Now.ToString("yyyy-MM-dd.HH.mm.ss");
				case "AUTOINCREMENT":
					int num = GetNextShotNumber(fileName);
					return "_" + num.ToString();
				default:
					return Properties.Settings.Default.SaveSuffix;
			}

		}

		private string GetFileName(bool useTitle)
		{
			if (useTitle)
			{
				string title = ExternWindow.GetActiveWindowTitle();
				return CleanFileName(title);
			}
			else
			{
				if (String.IsNullOrEmpty(Properties.Settings.Default.SaveFileName)) { return "Speed_Shot"; }
				else { return CleanFileName(Properties.Settings.Default.SaveFileName); }
			}
		}

		public string CleanFileName(string title)
		{
			//remove disallowed characters and spaces
			title = title.Replace(" ", "_");
			char[] invalidChars = Path.GetInvalidFileNameChars();

			foreach (char c in invalidChars)
			{
				title = title.Replace(c, '_');
			}

            if (title.Length > 50) { return title.Substring(0, 50); }
            else { return title; }
		}

		private int GetNextShotNumber(string fileName)
		{
			while (File.Exists(fileName + "_" + ShotNumber.ToString() + ".png") && ShotNumber < Int16.MaxValue)
			{
				ShotNumber++;
				Properties.Settings.Default.ShotNumber = ShotNumber;
			}

			return ShotNumber;
		}

		private void btnClose_Click(object sender, EventArgs e)
		{
			this.Close();
		}

		private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (e.CloseReason == CloseReason.UserClosing)
			{
                this.WindowState = FormWindowState.Minimized;
				this.Hide();
				
				e.Cancel = true;
			}
			
			Properties.Settings.Default.Save();
		}

		private void notifyIconMain_DoubleClick(object sender, EventArgs e)
		{
			this.WindowState = FormWindowState.Normal;
			this.Show();
		}

		private void mnuCapSettings_Click(object sender, EventArgs e)
		{
			this.WindowState = FormWindowState.Normal;
			this.Show();
		}

		private void mnuExit_Click(object sender, EventArgs e)
		{
			Application.Exit();
		}

		private void btnSaveDir_Click(object sender, EventArgs e)
		{
			FolderBrowserDialog fbd = new FolderBrowserDialog();
			fbd.ShowNewFolderButton = true;
			if (!String.IsNullOrEmpty(Properties.Settings.Default.SaveDirectory) && Directory.Exists(Properties.Settings.Default.SaveDirectory))
			{
				fbd.SelectedPath = Properties.Settings.Default.SaveDirectory;
			}

			DialogResult res = fbd.ShowDialog();
			if (res == DialogResult.OK)
			{
				Properties.Settings.Default.SaveDirectory = txtSaveDir.Text = fbd.SelectedPath;
			}
		}

		private void txtSaveDir_TextChanged(object sender, EventArgs e)
		{
			if (Directory.Exists(txtSaveDir.Text))
			{
				Properties.Settings.Default.SaveDirectory = txtSaveDir.Text;
			}
		}

		private void cmboSaveFile_TextChanged(object sender, EventArgs e)
		{
			Properties.Settings.Default.SaveFileName = cmboSaveFile.Text;
		}

		private void cmboSaveSuffix_TextChanged(object sender, EventArgs e)
		{
			Properties.Settings.Default.SaveSuffix = cmboSaveSuffix.Text;
		}

		private void chkPromptSave_CheckedChanged(object sender, EventArgs e)
		{
			Properties.Settings.Default.PromptSave = chkPromptSave.Checked;
		}

		private void chkCopyClipboard_CheckedChanged(object sender, EventArgs e)
		{
			cap.CopyToClipboard = chkCopyClipboard.Checked;
			Properties.Settings.Default.CopyToClipboard = chkCopyClipboard.Checked;
		}

		private void chkShowTips_CheckedChanged(object sender, EventArgs e)
		{
			Properties.Settings.Default.ShowTips = chkShowTips.Checked;
		}

		private void btnColor_Click(object sender, EventArgs e)
		{
			ColorDialog colorSelector = new ColorDialog();
			colorSelector.AllowFullOpen = false;
			colorSelector.FullOpen = false;
			colorSelector.SolidColorOnly = true;
			DialogResult res = colorSelector.ShowDialog();

			if (res != DialogResult.Cancel)
			{
				btnColor.BackColor = colorSelector.Color;
				Properties.Settings.Default.RegionWindowColor = btnColor.BackColor;
			}
		}

		private void cmboScreenModifier_SelectionChangeCommitted(object sender, EventArgs e)
		{
			if ((int)cmboScreenModifier.SelectedIndex == Properties.Settings.Default.CaptureRegionModifier ||
				(int)cmboScreenModifier.SelectedIndex == Properties.Settings.Default.CaptureWindowModifier)
			{
				MessageBox.Show("This modifier is already in use.\nChange the other setting first.");
				cmboScreenModifier.SelectedIndex = Properties.Settings.Default.CaptureScreenModifier;
			}
			else
			{
				Properties.Settings.Default.CaptureScreenModifier = (int)cmboScreenModifier.SelectedIndex;
			}
		}

		private void cmboRegionModifier_SelectionChangeCommitted(object sender, EventArgs e)
		{
			if ((int)cmboRegionModifier.SelectedIndex == Properties.Settings.Default.CaptureScreenModifier ||
				(int)cmboRegionModifier.SelectedIndex == Properties.Settings.Default.CaptureWindowModifier)
			{
				MessageBox.Show("This modifier is already in use.\nChange the other setting first.");
				cmboRegionModifier.SelectedIndex = Properties.Settings.Default.CaptureRegionModifier;
			}
			else
			{
				Properties.Settings.Default.CaptureRegionModifier = (int)cmboRegionModifier.SelectedIndex;
			}
		}

		private void cmboWindowModifier_SelectionChangeCommitted(object sender, EventArgs e)
		{
			if ((int)cmboWindowModifier.SelectedIndex == Properties.Settings.Default.CaptureRegionModifier ||
				(int)cmboWindowModifier.SelectedIndex == Properties.Settings.Default.CaptureScreenModifier)
			{
				MessageBox.Show("This modifier is already in use.\nChange the other setting first.");
				cmboWindowModifier.SelectedIndex = Properties.Settings.Default.CaptureWindowModifier;
			}
			else
			{
				Properties.Settings.Default.CaptureWindowModifier = (int)cmboWindowModifier.SelectedIndex;
			}
		}

		private void chkCaptureTaskbar_CheckedChanged(object sender, EventArgs e)
		{
			Properties.Settings.Default.CaptureTaskbar = chkCaptureTaskbar.Checked;
		}

		private void trackOpacity_Scroll(object sender, EventArgs e)
		{
			Properties.Settings.Default.RegonWindowOpacity = trackOpacity.Value;
		}

		private void chkUseTitle_CheckedChanged(object sender, EventArgs e)
		{
			Properties.Settings.Default.UseWindowTitles = chkUseTitle.Checked;
		}

		private void notifyIconMain_BalloonTipClicked(object sender, EventArgs e)
		{
			if (!String.IsNullOrEmpty(mostRecentCapture) && File.Exists(mostRecentCapture))
			{
				System.Diagnostics.Process.Start(mostRecentCapture);
			}
		}

	}

	public class ListItem
	{
		public string Key { get; set; }
		public int Value { get; set; }

		public ListItem(string key, int value)
		{
			this.Key = key;
			this.Value = value;
		}
	}
}
